/*
	
	

*** add : 
*  - after stable. :  donate ..
*  - 				: chest auto 
* 
*  - hurry	 :  study update  : OK : sp 30 view .. .
* 			: use -15 m  tem...!!!
* 			:  train when ef 0 : 50 
* 			: login dlg  change
* 			: hire 2nd H
* 			: integrate 10 sp  
	
	q -  Ac 
 ; hou - up 

-  finish : cd info  

* gift 
 Xpp0is3 

  use bless , gift ref 
  can sell. 

* Q - done 
* Q - ac  - build Fa : wait 20 
  :== build G mine
* Q - done bld F , acc - Bld W
 - bld W  , bld I  : wait 20 
* Q - W done   , I Ac - I Done
* Q - G ac, G done
* Q - fu - ac
  -- facil up,   wait 1:30  
   -- get cdinfo   -- skip 
  -- % bless
* Item  - use bless 
 : facil - done, cd, user info 
* overvie - getuserinfo

* Q - facil done 
* Q - bld barr acc
* bld barr 
 == bld area  : wait 1:50

* Q - bld Bar done ,  
* Q - train acc 
  == train : wait 2:30
  == hire H 

*Q - train done 
* Q - hire H  acc , done

* Q -  build uni    
== bld uni : wait 1:20 

* Q  -  bld uni done,   forge acc
 == study forge  : wait 11:00

 == bld house  : wait 2:00 
 == bld brr :  wait 5:00
 == bld area : wait 40;50 
 ------ wait until study end 

 * buy gold chest 
  - use 

* sell every ite 
  x 3 * 3 ����, ������ ��. 
: total : 41000 

* set user name :  


* buy shop  
 * buy All To ( ania ) . 

* trade : 310089

 * check trade wait time :  

--------- step 1  finished

* Q - forge done  , Wall acc 

step 2  : 
---  check ? step 2 ? 
local storage : step ����. 
gold > 50 000 

- bld area  3 , bld barr  5
= bld uni 3 , study  scout 1


--- cur action : local storage �� ����.

* �ֱ������� runner �� 310089 �� ã�Ƽ� �� �ֱ�. 
* 
** get cit info �� �ڱ� �ȸ��� Ȯ����.
 1 �� ����.. 

- bld uni ,  bld hou, bld ba\

* buy All To  2800089
* get cit info 
 _ sold  -> next step 3 

-- �Ʒ� �� �ʿ� ����.  reward �� �� ����

* Q :  wall done,  res mgr acc
* Q : res mgr done 




*******************
* Check G :
*  
*   - find tradelit,  will, trade list : 
*      ==  exist : w no check G
* 
*  - if can find mytem in tradelist 
*  		:skip buy 
* 
*   - if find my tem in  will /trade list
*   	: skip trade  
* 


 
*/	
"use strict";


// step 1 :  seq Q : bld & sttudy  
//		:  trade  on  

// step 2 : wait till sold trade item

// step 3 : when g > 30 0000  :   bld, strdy, train, check res < 20 000 : trade again 	
function CInitQuest() {
	this.objName = "CInitQuest: ";
	
	this.step = 1; 
	this.nth = -1;
	this.actionSeq = new CActionSeq();

	debug.log(this, ' Created Init Qst ');
	
	var self = this;
	this.force_stop = false;
	em.cbs.forcestop.add ( function() {self.force_stop = true; 
							debug.log(self,'Set ForceStop ::' , self.force_stop);  });
	
	if ( em.place == 'office') {
		this.cit_timeout = 125000;
		debug.log( this, ' OFFICE timeout ', this.cit_timeout) ;
	} else {
		this.cit_timeout = 60000;
	}
	
	// set trade tem & price by server
	if ( CDB.getCurUserInfo().serverinfo.name == 'Ania') {
		this.tem_id = 113; // ally token 
		this.tem_price = 280089;
		this.tem_step3_price = 1500089;
		this.tem_type = 3; 
	} else {
		// Hipo 
		this.tem_id = 73; // wp 
		this.tem_price = 160089;
		this.tem_step3_price = 1400089;
		// this.tem_step3_price = 800089;
		this.tem_type = 1; 
	}
	
	debug.log( this, ' SET Trade Id ; ', this.tem_id, ' Price: ', this.tem_price, ' Type:', this.tem_type);
	
	
	this.taskSeq =  [
		// login, ��   initial  task list is done when change user . 
		// { name: 'checkQst', fn: self.conductQst, param: { 'action': 'task_list', 'id': 0 } ,retry: 0 },
		// Q - acc house 
		{ name: 'checkQst', fn: self.conductQst, param: { 'action': 'task_up', 'id': 1 } ,retry: 0 },
		// bld Hou
		{ name: 'buildHouse', fn: self.conductBld, param: { type: CDB.BUILD.HOU.type, lv: 0} , retry: 0 },
		// gift today : ignore...  
		// GET /game/goods_api.php?jsonpcallback=jsonp1326014287244&_=1326014414673&key=0314fac3e037989c062370584d3dc99b&action=gift&id=168&_l=en&_p=EW-DROID HTTP/1.1

		//  * buy gold chest  & use 
		{ name: 'buy_Gold_Chest', fn: self.buyGemItem, param: { cat: 5 , id: 131} ,retry: 0 }, // 49 "id":75644,"sid":131, : g chest 
		{ name: 'useItem_Chest__!!!', fn: self.useItem, param: { type: 3 , sid: 131,  id: 75644 , num: 1} ,retry: 0 }, // 
		{ name: 'useItem_ref___!!!', fn: self.useItem, param: { type: 3 , sid: 169, id: 75606 , num: 1} ,retry: 0 }, // "id":75606,"sid":169, : ref  

/*
	{"id":75612,"sid":128,"num":1},"use":1,"sale":0},
{"item":{"id":75616,"sid":190,"num":1},"use":1,"sale":50000},
{"item":{"id":75615,"sid":188,"num":1},"use":2,"sale":0},
{"item":{"id":75611,"sid":126,"num":1},"use":1,"sale":0},
{"item":{"id":75613,"sid":161,"num":2},"use":1,"sale":0},
{"item":{"id":75610,"sid":80,"num":1},"use":1,"sale":0},
{"item":{"id":75617,"sid":153,"num":1},"use":1,"sale":0}]}})
*/
		// * sell item.
		{ name: 'saleItem_ref_118_3', fn: self.saleItem, param: { type: 3 , sid: 118, id: 0 , num: 3} ,retry: 0 }, //  ref 
		{ name: 'saleItem_ref_161_3', fn: self.saleItem, param: { type: 3 , sid: 161, id: 0, num: 3} ,retry: 0 }, //  ref  &id=75620 , // sid 161
		{ name: 'saleItem_ref_115_3', fn: self.saleItem, param: { type: 3 , sid: 115, id: 0, num: 3} ,retry: 0 }, //  ref  &id=75618  , sid  115
		
	
		// wait complet  cd type 1 
		{ name: 'checkCd_WaitHOU', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.HOU.type} , retry: 0 },
		//		* Q - done : hou
		{ name: 'checkQst_DoneHou', fn: self.conductQst, param: { 'action': 'task_end', 'id': 1} ,retry: 0 },

		// expand bld slot  with bless 	
		// gift jan
		{ name: 'getGift', fn: self.getGift, param: 'Xpp0is3', retry: 0 },// 1  , 5v6hczj : x-ma
		// { name: 'getGift', fn: self.getGift, param: '3hp6xfs', fault_action: 'skip', retry: 0 },//
		// { name: 'getGift', fn: self.getGift, param: 'Xpp0is3',retry: 0 },	// 1
		
		{ name: 'useBless30', fn: self.useItem, param: { sid: 167, id: 75614 , num: 1} ,retry: 0 },	//  11 "  id":75614,"sid":167, 30days 
		
		// build Farm
		{ name: 'checkQst_UP_BldFar', fn: self.conductQst, param: { 'action': 'task_up', 'id': 2 } ,retry: 0 },
		{ name: 'buildFAR', fn: self.conductBld, param: { type: CDB.BUILD.FAR.type, lv: 0} ,retry: 0 },
		{ name: 'buildWoo_sawmill', fn: self.conductBld, param: { type: 1 /* mill */, lv: 0} ,retry: 0 },
		
		
		// check Q 
		// { name: 'checkQst_LIST', fn: self.conductQst, param: { 'action': 'task_list', 'id': NaN } ,retry: 0 },
		{ name: 'checkCd_WaitBldFar', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.FAR.type} , retry: 0 },
		 
		{ name: 'checkQst_END_BldFar', fn: self.conductQst, param: { 'action': 'task_end', 'id': 2 } ,retry: 0 },
		{ name: 'checkQst_UP_BldIro', fn: self.conductQst, param: { 'action': 'task_up', 'id': 14 } ,retry: 0 },	// I 
		// build w, gm 		
		{ name: 'build_IronMine', fn: self.conductBld, param: { type: 2 /* w */, lv: 0} ,retry: 0 },
		{ name: 'build_GolMin', fn: self.conductBld, param: { type: 3 /* g m */, lv: 0} ,retry: 0 },	// take longer time
	
	
		
		// buy All Tk 
		{ name: 'buy_All_Tk______OR_WP', fn: self.buyItem, param: { type: self.tem_type , id: self.tem_id} ,retry: 0 }, //  510
		
		// trade.. up. .. 
		{ name: 'trade_regi_AllTk__!!!!!_OR_WP', fn: self.tradeReg, param: { sid: self.tem_id, id: 0, num: 1, price: self.tem_price } ,retry: 0 }, //  11
	
		// check trade success 
		{ name: 'Check_TRade_List', fn: self.checkTrade, param: { sid: self.tem_id } ,retry: 0 },	//  
		
		// wait complet  cd type 1 
		{ name: 'checkCd_WaitMil', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: 1} , retry: 0 },
		
		{ name: 'checkCd_wait_GolMin', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: 3 } , retry: 0 },

	
	
		// Check Q 
		// { name: 'checkQst_LIST', fn: self.conductQst, param: { 'action': 'task_list', 'id': NaN } ,retry: 0 }, // 
		{ name: 'checkQst_END_GolMin', fn: self.conductQst, param: { 'action': 'task_end', 'id': 14 } ,retry: 0 },	//  gm
		
		{ name: 'checkQst_UP_Woo', fn: self.conductQst, param: { 'action': 'task_up', 'id': 15 } ,retry: 0 },	//  w 
		{ name: 'checkQst_END_Woo', fn: self.conductQst, param: { 'action': 'task_end', 'id': 15 } ,retry: 0 },	//  
		{ name: 'checkQst_UP_I?', fn: self.conductQst, param: { 'action': 'task_up', 'id': 16 } ,retry: 0 },	//  
		{ name: 'checkQst_END_I?', fn: self.conductQst, param: { 'action': 'task_end', 'id': 16 } ,retry: 0 },	//  

		// build facil
		{ name: 'checkQst_UP_Fac', fn: self.conductQst, param: { 'action': 'task_up', 'id': 3 } ,retry: 0 },	//  30  
		{ name: 'build_Facility', fn: self.conductBld, param: { type: CDB.BUILD.FAC.type, lv: 0} ,retry: 0 }, // wait 1: 30 
		
		// get bless & use bless 
		{ name: 'useBless7777', fn: self.useItem, param: {"id":75635,"sid":166 , num : 1} ,retry: 0 }, //  7 days "id":75635,"sid":166,

			// build barr		
		{ name: 'build_Barr', fn: self.conductBld, param: { type: CDB.BUILD.BAR.type, lv: 0} ,retry: 0 }, //barr 1:50
			// are
		{ name: 'build_Area', fn: self.conductBld, param: { type: CDB.BUILD.ARE.type, lv: 0} ,retry: 0 }, //  longer tha barr
		
		{ name: 'checkCd_Wait_FAC', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.FAC.type } , retry: 0 },
		{ name: 'checkQst_END_BldFAC', fn: self.conductQst, param: { 'action': 'task_end', 'id': 3 } ,retry: 0 },	// facil   
		
		// bld barr 
		{ name: 'checkQst_UP_BAR', fn: self.conductQst, param: { 'action': 'task_up', 'id': 4 } ,retry: 0 },	// bar   
			
		//get use info 
		{ name: 'getUserInfo', fn: self.getUserInfo, param: { } ,retry: 0 }, // why?? 

		{ name: 'checkCd_Wait_BAR', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.BAR.type } , retry: 0 },
		{ name: 'checkQst_END_BAR', fn: self.conductQst, param: { 'action': 'task_end', 'id': 4 } ,retry: 0 },	// bar   
			
		{ name: 'checkQst_UP_TrainSol', fn: self.conductQst, param: { 'action': 'task_up', 'id': 17 } ,retry: 0 },	// train sol   
		{ name: 'train_Infan', fn: self.trainSol, param: { 'sol_type': 1, 'sol_num': 10 } ,retry: 0 },	// train sol
		

		// bld uni 
		{ name: 'build_UNI', fn: self.conductBld, param: { type: CDB.BUILD.UNI.type , lv: 0} ,retry: 0 }, //barr 1:20
		
		// wait  sol train    
		{ name: 'checkCd_Wait_Train_Inf', fn: self.checkCd, param: { cdtype: CDB.CDS.TRAIN, target: 1 /*sol type*/ } , retry: 0 },
		{ name: 'checkQst_END_TrainSol', fn: self.conductQst, param: { 'action': 'task_end', 'id': 17 } ,retry: 0 },	// train sol   

		// hire h 
		{ name: 'checkCd_Wait_AREN', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.ARE.type } , retry: 0 },
		{ name: 'hire_H', fn: self.hireH, param: {  } ,retry: 0 },	// 
		
			// done hire H 
		{ name: 'checkQst_UP_AREN', fn: self.conductQst, param: { 'action': 'task_up', 'id': 5 } ,retry: 0 },	//  ARENA 
		{ name: 'checkQst_END_AREN', fn: self.conductQst, param: { 'action': 'task_end', 'id': 5 } ,retry: 0 },	// ARENA
		
		//
		{ name: 'checkQst_UP_Hire_H', fn: self.conductQst, param: { 'action': 'task_up', 'id': 18 } ,retry: 0 },	// hire H    
		{ name: 'checkQst_END_Hire_H', fn: self.conductQst, param: { 'action': 'task_end', 'id': 18 } ,retry: 0 },	// hire H     
		
		// bld uni 
		{ name: 'checkQst_UP_Bld_Uni', fn: self.conductQst, param: { 'action': 'task_up', 'id': 6 } ,retry: 0 },	// bld uni   
		{ name: 'checkCd_Wait_Bld_Uni', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.UNI.type } , retry: 0 }, 
		{ name: 'checkQst_END_Bld_Uni', fn: self.conductQst, param: { 'action': 'task_end', 'id': 6 } ,retry: 0 },	// 
	
		//  study forge
		{ name: 'checkQst_UP_Strudy_Forge', fn: self.conductQst, param: { 'action': 'task_up', 'id': 19 } ,retry: 0 },	// study forge  
		{ name: 'Study_Forge', fn: self.conductStudy, param: { 'tech': CDB.STUDY.FORGING.type , lv: 0} ,retry: 0 }, // 45  //  wait 11:00


		// bld house 2 & barr 2  & arena 2 
		{ name: 'build_Area_2', fn: self.conductBld, param: { type: CDB.BUILD.ARE.type , lv: 1} ,retry: 0 }, //barr 1:20
		{ name: 'build_Hou_2', fn: self.conductBld, param: { type: CDB.BUILD.HOU.type , lv: 1} ,retry: 0 }, //barr 1:20
		{ name: 'build_Barr_2', fn: self.conductBld, param: { type: CDB.BUILD.BAR.type , lv: 1} ,retry: 0 }, //barr 1:20
		
		{ name: 'checkCd_Wait_Study_Forge', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.STUDY.FORGING.type } , retry: 0 }, 
		{ name: 'checkQst_END_Study_Forge', fn: self.conductQst, param: { 'action': 'task_end', 'id': 19} ,retry: 0 },	//  forge done

/*
		// WAIT anrea 		
		{ name: 'checkCd_Wait_Aren2', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.ARE.type } , retry: 0 },

		// bld aran 3 		
		{ name: 'build_Area_2', fn: self.conductBld, param: { type: CDB.BUILD.ARE.type , lv: 1} ,retry: 0 }, //barr 1:20
		{ name: 'checkCd_Wait_Aren2', fn: self.checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.ARE.type } , retry: 0 },
		 */

		// wall acc 
		{ name: 'checkQst_UP_BldWall', fn: self.conductQst, param: { 'action': 'task_up', 'id': 7} ,retry: 0 },	//  wall 

		{ name: 'Check_TRade_List', fn: self.checkTrade, param: { sid: self.tem_id } ,retry: 0 },	//  wall 
	];
	
	
	
	/*
		 step 3 table 
	*/
	this.step3_bld_tbl = [
		[ CDB.BUILD.BAR.type, 1 ],
		[ CDB.BUILD.ARE.type, 1 ],
		
		[ CDB.BUILD.FAC.type, 1 ],
		[ CDB.BUILD.FAC.type, 2 ],
		[ CDB.BUILD.FAC.type, 3 ],
		
		[ CDB.BUILD.HOU.type, 1 ],
		[ CDB.BUILD.HOU.type, 2 ],
		
		[ CDB.BUILD.UNI.type, 1 ],
		[ CDB.BUILD.UNI.type, 2 ],
		[ CDB.BUILD.UNI.type, 3 ],
		
		[ CDB.BUILD.HOU.type, 3 ],
		
		[ CDB.BUILD.ARE.type, 2 ],
		[ CDB.BUILD.ARE.type, 3 ],
		
		[ CDB.BUILD.BAR.type, 2 ],
		[ CDB.BUILD.BAR.type, 3 ],
		
		[ CDB.BUILD.FAC.type, 4 ],	
		[ CDB.BUILD.FAC.type, 5 ],	
		[ CDB.BUILD.HOU.type, 4 ],
		[ CDB.BUILD.HOU.type, 5 ],
		
		[ CDB.BUILD.BAR.type, 4 ],
		[ CDB.BUILD.UNI.type, 4 ],

		[ CDB.BUILD.FAC.type, 6 ],	
		[ CDB.BUILD.HOU.type, 6 ],
		[ CDB.BUILD.BAR.type, 5 ],
		[ CDB.BUILD.UNI.type, 5 ],
		
		[ CDB.BUILD.BAR.type, 6 ],
		[ CDB.BUILD.UNI.type, 6 ],
		
		[ CDB.BUILD.BAR.type, 7 ],
		[ CDB.BUILD.UNI.type, 7 ],
		[ CDB.BUILD.FAC.type, 7 ],
				
		[ CDB.BUILD.BAR.type, 8 ],
		[ CDB.BUILD.UNI.type, 8 ],
		[ CDB.BUILD.FAC.type, 8 ],		

		[ CDB.BUILD.BAR.type, 9 ],
		[ CDB.BUILD.UNI.type, 9 ],
		[ CDB.BUILD.FAC.type, 9 ],
				
		[ CDB.BUILD.BAR.type, 10 ],
		[ CDB.BUILD.UNI.type, 10 ],
		[ CDB.BUILD.FAC.type, 10 ],		

		[ CDB.BUILD.BAR.type, 11 ],
		[ CDB.BUILD.UNI.type, 11 ],
		[ CDB.BUILD.FAC.type, 11 ],		
	];	  	

	this.step3_study_tbl = [
		[ CDB.STUDY.FORGING.type, 1 ],
		[ CDB.STUDY.MARCHING.type, 1 ],
		[ CDB.STUDY.SCOUTING.type, 1 ],
		[ CDB.STUDY.LOGISTICS.type, 1 ],
		[ CDB.STUDY.EFF_TRAINING.type, 1 ],
		[ CDB.STUDY.EFF_TRAINING.type, 2 ],
		[ CDB.STUDY.EFF_TRAINING.type, 3 ],
		[ CDB.STUDY.EFF_TRAINING.type, 4 ],
		[ CDB.STUDY.EFF_TRAINING.type, 5 ],
		[ CDB.STUDY.EFF_TRAINING.type, 6 ],
		[ CDB.STUDY.EFF_TRAINING.type, 7 ],
		[ CDB.STUDY.EFF_TRAINING.type, 8 ],
		[ CDB.STUDY.EFF_TRAINING.type, 9 ],
		[ CDB.STUDY.EFF_TRAINING.type, 10 ],
		[ CDB.STUDY.EFF_TRAINING.type, 11 ],
		[ CDB.STUDY.EFF_TRAINING.type, 12 ],
		[ CDB.STUDY.EFF_TRAINING.type, 13 ],
		[ CDB.STUDY.EFF_TRAINING.type, 14 ],
		[ CDB.STUDY.EFF_TRAINING.type, 15 ],
	];	  	
	
};		
	
CInitQuest.prototype = {

	

	initialize: function() {


		this.step = 1; 
		this.nth = -1;
		this.force_stop = false;
		
		
		// test interface
		var start_opt ; var start_nth =0; var len =0;
		if ( $('#h_level').val() ) {
			start_opt = $('#h_level').val().split(",");
			debug.log ( this, ' Got opt : ' , start_opt);
			start_nth = parseInt( start_opt[0] );
			len = start_opt[1] ? parseInt( start_opt[1] ) : 0;	// not set .. to the end.. 
		}
		
		debug.log ( this, ' h level', start_nth , 'len', len);

		var seq_len = 		this.taskSeq.length ;
		
		if ( len > 0  && start_nth + len < seq_len ) {
			// cut : splice :: This method changes the original array!
			this.taskSeq.splice( start_nth + len , seq_len - start_nth - len ); // start , n 
			debug.log(this, ' ori seq_len: ', seq_len,  ' \t Spliced Seq : len : ', this.taskSeq.length );

		}
		
		if ( start_nth ) {
			// do only 1 action 
			this.nth = start_nth -1; // start with ++1
			 
			// var end  = ( start_nth + len >  seq_len ) ? seq_len : start_nth + len;
			// this.taskSeq = this.taskSeq.slice( start_nth , end ); // setart, end 
			// debug.log(this, ' ori seq_len: ', seq_len,  ' \t slice ed  : len : ', this.taskSeq.length );
			
			this.test_one_action = true;
			this.start_nth = start_nth;
			return;
		} 
		
		// g > 20 0000  start at step 3 
		var res  = em.cstlmgr.getCurCstl().res;
		if ( res.g > 80000 ) {
			this.step = 3;
			return;
		}
				
		
		// get prev state 
		this.getStoredState();
	},
	
	reinit: function() {
			this.nth = -1;
	},
	
	
	// when restart : get prev  proceeding state 
	getStoredState: function() {
		// get stored state 
		var stored_state = CUtil.getStorage('InitQ_' +  CDB.getCurUserName());
		if ( stored_state ) {
			this.step = stored_state.step;
			this.nth = stored_state.nth;
			debug.log( this, ' Get prev stored stgate: ',stored_state , this.step, this.nth );
		}
		else {
			debug.log( this, 'No stored Info : STart New ');
		}
	},

	stampState: function( ) {
		debug.log(this,  'stampState !!! ');
		CUtil.saveStorage('InitQ_' +  CDB.getCurUserName() , { step: this.step , nth: this.nth } );		
	 },	
	
	start: function( ) {
		debug.log(this,  'test start !!! ');
		
		if ( this.step >= 2) {
			this.startStep3();
			return;
		}
		

				
		this.step1 = {};

		// check cit info : to update lv 
		this.step1.cit_timer = setInterval( function() {
			em.tasks.getCitInfo( em.cstlmgr.curCstlID(), 
					function() { });	// none :  		
			}, this.cit_timeout) ; // 30sec 
			 		
		// else start step 1 at prev nth 
		// get Q task 
		var task = this.getNextTask(); 
		// go 1st job 
		this.doTask(task);
	 },
		
	Step1Finished: function() {
		debug.log (this, 'Step1Finished finishied!!!');
		
		// wait until all tk is sold 
		this.step = 2;
		
		this.startStep2();
	},

	getNextTask: function () {
		
		// test 
		// if ( this.test_one_action  && this.nth > this.start_nth  ) return; 
		
		// force stop 
		if ( this.force_stop ) return; 
		 
		if ( ++this.nth >= this.taskSeq.length) {
			// test 
			if ( this.test_one_action ) return;
			
			// done  step 1  
			this.Step1Finished();
			return;		
		}
		debug.log( this, ' cur task : ',  this.nth, this.taskSeq[this.nth]) ;
		return this.taskSeq[this.nth];	
	},
	

	doTask: function( task ) {
		
		if ( task && task.fn ) {
			debug.log(this, '\n\n ============= Cur Do task:', task.name, task.retry, task.param);
			// debug.log( this, ' ============ doTask: ', task);
			// debug.log(this, ' \n\n				Cur task: ', task.name, task.retry);
			// debug.log(this, ' Cur task: \n\n\n ', task.name, task.retry);
			
			em.util.print_result( 'INITQ: ' + task.name + ' : Start == s:n ' + this.step + ':' + this.nth);
			
			task.fn.apply(this, [ task, task.param , this.doNext]);
		} else {
			debug.log ( this, 'ERROR INVLAID TASK !!!');
		}
	},
	
	// recv result from prev task 
	// check  task entity 
	// sucess / fail check 
	//  retry? or skip 
	// wait complete ? -> set interval .  check cd list 
	//    when  cd is end - > re enter this. 
	// do next 
	doNext : function(task, result) {
		var self = this; 
		
		if (!task) {
			debug.log( this, 'No Task... specified.. : return');
			return;
		}
		
		// check  task entity
			// noti ui cur state 
		debug.log(this, ' 	Done task:', task.name, task.retry);
		debug.log(this, ' 	task Result :', result.succ ,  result);
		debug.log(this, ' 				Done task: \n', task.name, task.retry);
		// debug.log(this, ' Done task: \n\n\n ', task.name, task.retry);
		em.util.print_result( 'INITQ: ' + task.name + ' : ' + (result.succ == true ? 'Succ' : 'Fail') );
		
		if ( result.succ ) {
			
			// stamp state 
			this.stampState( task);
			

			// if need to wait  
	/*
			if ( task.wait ) {

				debug.log(this, ' task.wait for task completion :', CUtil.TimeToString(result.waittime));
					var cdtype = result.ret.cdlist[0].cdtype; // result.ret.cdtype
					var target = parseInt( result.ret.cdlist[0].target ); // result.ret.cdtype
	
					this.wait_timer = setInterval ( function() {
						// check cdlist
						
						var bCompleted =  em.cstlmgr.bCompleteCdlist(cdtype, target );
						debug.log(this, 'complete ? :', bCompleted);
						if (  bCompleted  ) {
							// clear this timer 
							clearInterval( self.wait_timer);
							
							// send task to do next
							self.doNext( { name: task.name }, { succ: true} );
						}
											   }, 2000); // each 2sec 
	
			} else {
				*/
				
				// just do next
				var task = this.getNextTask(); 
				setTimeout( function() { self.doTask( task ); }, 1000 ); 
		 
		} else {
		//  when fail.. go next !! or stop !!.  
			if ( task.fault_action == 'abort' ) {
				alert( ' Task is Failed.. Critical !' + task.name);
				return;
			} else {
				debug.log(this, '\n \t ************ Error in action ', task , ' just go next act '); 
				// just do next
				// self.doTask( this.getNextTask() );
				setTimeout( function() { self.doTask( self.getNextTask() ); }, 1000 );
			}
		}
	},
	

	
	
	
	/*
		 step 2  
	*/
	
	// wait until ally tk is soled 
	startStep2: function() {
		var self = this;
		clearInterval( this.step1.cit_timer );
		// set timer for cit info 
		this.cit_timer = setInterval( function() {
					// get cit info : update res 
					em.tasks.getCitInfo( em.cstlmgr.curCstlID(), 
							function(data) {
						
								debug.log( self, ' STEP 2: Wait trade sold!! ', data);
								self.checkAllyTkSold( 2, 
									function () {	// done : soled 
										
										// clear  & go step 3 
										clearInterval( self.cit_timer );
										self.step = 3;
										setTimeout( function() { self.startStep3(); } , 0 );
									}
								);
							}); // get cit info  		
				}, this.cit_timeout) ;
		
	
		// check ally tk is sold : when sold go step 3 
/*
		var self = this;
		function checkAllyTkSold () {
			var res  = em.cstlmgr.getCurCstl().res;
			if(self.step == 2 &&  res.g > self.prev_res.g + 200000) {
				debug.log( self, ' Gotcha . TK is sold , move next step 3 :', res.g);
				clearInterval( self.cit_timer );
				self.step = 3;
				setTimeout( function() { self.startStep3(); } , 0 );
			}
			self.prev_res = res;
		};*/

		 
	},
	
	checkAllyTkSold: function  ( step,  cb ) {
		var res  = em.cstlmgr.getCurCstl().res;
		debug.log( this, ' checkAllyTkSold,  IN  step :', step, ' new G: ',  res.g);
		
		// first check : just store.. res 
		if ( ! this.prev_res ) {
			// deep copy 
			this.prev_res = {};
			$.extend( this.prev_res , res);
			return;
		}
		
		debug.log( this, ' checkAllyTkSold,  this.prev_res.g :', this.prev_res.g, ' new G: ',  res.g);
		if( step >= 2 &&  res.g > this.prev_res.g + 100000) {
				debug.log( this, ' Gotcha . TK is sold ,  IN  step :', step, ' new G: ',  res.g);
				cb ( ) ;
		}
		// this.prev_res = res;
		// deep copy 
		$.extend( this.prev_res , res);
	},
	
	/*
		 step 3  -------------------------
	*/
	
	__STEP3___BEGIN______: function() {},
	startStep3: function() {
		var self = this;
		this.step3 = {};
		// this.step3.cit_cnt = 0;
		
		// set step 3 
		this.stampState();
		 
		// check cit info : to update lv 
		// & check to sold trade  item . 
		this.step3.cit_timer = setInterval( function() {
			em.tasks.getCitInfo( em.cstlmgr.curCstlID(), 
					function() {
						//check trade 
						self.checkAllyTkSold( 3, 
							function () {	// done : soled 
								self.step3.tradingAllyTk = false;
							}
						);
						
						// check sutdy
						// -- will be done by sp30 panel : updatae priodically 
/*
						if ( self.step3.cit_cnt++ > 3 ) {
							self.step3.cit_cnt = 0;
							
						}
*/
				}); 		
			}, this.cit_timeout) ;
			 
		this.step3Monitor();
	},
	
	step3Monitor: function() {
		var outer = this;
		var self = this;
		var cstlinfo = em.cstlmgr.getCurCstl();
		
		debug.log ( this, ' step3Monitor ::', this.step3 );
		
		// force stop 
		if ( this.force_stop ) return; 


		var actions = {
			name: 'step3',
			context: this, 
			action_table: [

			// check Gl 
				{ 
					cmd: 'check G',
					doParam: {  },
					cb : function(data) {
							debug.log ( self, 'check G ::', data ); 	
							if ( typeof data === 'object' &&  data.code == 0 ) {
								debug.log ( self, 'check G :: Success ~~~~~~~~~~~', data );
							}
							setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
						},
					doFunc:	 self.checkG,
				},	
			// try bld 
				{ 
					cmd: 'Try bld',
					doParam: { },  
					cb : function(data) {
									debug.log ( self, ' Try bld ::', data ); 	
									setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
					},
					doFunc:	 self.tryBld,
				},	
			// try study
				{ 
					cmd: 'Try study',
					doParam: { },
					cb : function(data) {
									debug.log ( self, ' Try study ::', data ); 	
									setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
						},
					doFunc:	 self.tryStudy,
				},	
				// try train 
				{ 
					cmd: 'Try Train',
					doParam: { 'type': 2, 'num': 5000 } , 	// disband all  
					cb : function(data) {
									debug.log ( self, ' Try Train ::', data ); 
									setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
						},
					doFunc:	 self.tryTrain,
				},					
			// donate 
				{ 
					cmd: 'Try Donate',
					doParam: { },  
					cb : function(data) {
									debug.log ( self, ' Try Donate ::', data ); 	
									setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
						},
					doFunc:	 self.tryDonate,
				},	

				],
				done_cb:function () { 
							// restart this action seq after some time. 
							setTimeout( function() { self.step3Monitor.call( self ); } , this.cit_timeout + 5000 ); // 1 min later 
					 },			// cb for complete action  	
		};
	
		this.actionSeq.setAction(actions);
		this.actionSeq.start();
	},
	
	// check possible  
	// disband
	// train 
	tryTrain: function(aparam, cb) {
		var cstl = em.cstlmgr.getCurCstl();
		var barr_lv = cstl.city[ CDB.BUILD.BAR.pos ];
		
		var ef_lv = cstl.studies[ CDB.STUDY.EFF_TRAINING.pos ] !== undefined ?  cstl.studies[ CDB.STUDY.EFF_TRAINING.pos ][1] : 0;

		debug.log( this, ' tryTrain ::', barr_lv, ef_lv, cstl, em.tasks);

		// cstl.studys[ s.pos ][1]))	//lv
		// cstl.studys[ s.pos ][2]))	//possible
		
		// check possible  : ef > 0 , bar > 2  : 
		// XXX:  not train when ef is  0 !!!!  ineffective 
		if ( barr_lv < 3 ||  ef_lv < 1) {
			debug.log( this, ' Can t  train Sp ', barr_lv, ef_lv);
			cb(-1);
			return;
		}
		
		//	check cd list if training..
		var cstlinfo = em.cstlmgr.getCurCstl();  
		cstlinfo.clearExpired (CDB.CDS.TRAIN );
		var ings = cstlinfo.findCdTypes (CDB.CDS.TRAIN );
		if ( ings.length >= 1 ) {
			debug.log( this, ' Train is doing...');
			cb(-1);
			return;
		}
	  // disband : update cur sol state : check max num
	  var trs  = { s: aparam.num , type: aparam.type, num: aparam.num }; // max 50000  : all spy disband 
	  em.tasks.disbandSols (trs, function(result) {
	  		if ( result.code != 0 ) {
	  			debug.log ( self, ' ERROR in disband!!', result);
	  		}
	  		// do train 
	  		spTrain();
	  } ); 
	  
		// train  after disband 
		function spTrain() {
			debug.log(self, 'spTrain');
			var trs  = {type : 2 , num : ef_lv * 100 };	
			// calc res  : compare to cstl res 
			var res  = em.cstlmgr.getCurCstl().res;
			
			// calulate resorece !!!
			var per_res =  CDB.SOLS.COST[trs.type];
			var cost = {};
			$.each( Object.keys(per_res) , function (i, item) { 
				cost[item] = per_res[item] * trs.num; 
			});
			
			console.log( ' per_res ' , per_res);
			console.log( ' cost ' , cost);
			
			debug.log( this, ' build Need cost: ', cost);
	
			var calc_ret = CUtil.calcNeedRes(res, cost);
			
			em.tasks.trainSol(em.cstlmgr.getCurCstlIdx(), 
						trs,		
						{g2f: calc_ret.exchange.f,  g2w: calc_ret.exchange.w, g2i: calc_ret.exchange.i, total:calc_ret.exchange.total } , 
						function (data) {
							cb(data);	 
						} 
				);
		};	
		
	},	
	
	
	// check empty bld slot 
	// get bld table.  
	// check cur bld state 
	// pop done bld action
	// try next bld 
	
	// 1. check slot 
	// 2. cur blding ?  
	// N :  lv :  > curlv  ==> doBld  or skip  
	//  Y :  find next not blding WB ( wanted bld )
	// 		pop wb from tbl :  
	//			wb is blding - > push ings
	//			wb is not blding  -> do Bld  -> return
	//			reorganaze tbl :  ings + remain Tbl 
	tryBld:  function(aparam, cb) {
	  	var cstlinfo = em.cstlmgr.getCurCstl();
	  	
		// check empty bld slot
		cstlinfo.clearExpired (CDB.CDS.BLD );
		var bld_cds = cstlinfo.findCdTypes (CDB.CDS.BLD );
		if ( bld_cds.length >= 3 ) {
			debug.log( this, ' All 3 slot is blding...');
			cb(-1);
			return;
		}

		function bNowBlding (type) {
			// check current blding ?  : type, lv  both same. 
			var now_blding = bld_cds.filter ( function(el) { 
				return ( el.target == type )  ; 
				});
			return now_blding.length;
		}
			
		// get bld table.
		// [name, lv, type]  
	  	var cur_blds = cstlinfo.getBlds();
	  	// check cur bld state 
	  	while ( this.step3_bld_tbl.length !=0  ) {

	  		// get first  // [ CDB.BUILD.FAC.type, 1 ],
	  		var wb = this.step3_bld_tbl.shift() ;

			debug.log( this, 'tryBld :: cur : ', cur_blds, ' wb:', wb);
	  		// get  cur lv of wb    : cur_bld [ name, lv, type ]
	  		var cur_wb = CUtil.findElArrByValPos ( cur_blds,  wb [0]  /* bld type */ , 2 /* positoin */ );
	  		// var cur_wblv = (cur_wb !== undefined) ? cur_wb[1] : 0 ;
	  		// bld is always has value ..  in city info array   	
			
			// lv check :  cur lv > want lv : skip   
			if ( cur_wb[1] >= wb[1]  ) { // already done : cur 8,  want  8  : done..
				debug.log( this, 'tryBld :  Already Done: ', wb, cur_wb);
				continue; 
			} 
			
			if ( bNowBlding(wb[0]) ) {
				debug.log( this, ' Now Blding.. :: ', wb,  ' cur cds: ', bld_cds ,'Find Alt WB : ') ;
				
				// find not blding wb 
				var ings = [];
				
				// push back cur wb  !!!  
				ings.push(wb); 
				
				var avail_wb;
				/// pop wbs &   put  ings arr  
				while ( this.step3_bld_tbl.length !=0  ) {
						var alt_wb = this.step3_bld_tbl.shift();
						debug.log( this, ' Alt WB : ' , alt_wb) ;
						
						// get  cur lv of wb    : cur_bld [ name, lv, type ]
				  		var cur_alt_b = CUtil.findElArrByValPos ( cur_blds,  alt_wb [0]  /* bld type */ , 2 /* positoin */ );
						// lv check :  cur lv > want lv : skip   
						if ( cur_alt_b[1] >= alt_wb[1]  ) { 
							debug.log( this, 'tryBld :  Already Done: alt_wb ', alt_wb, ' cur_alt_b:', cur_alt_b);
							continue; 
						} 
						
						if ( bNowBlding(alt_wb[0]) )  {		// is blding ?
							debug.log( this, ' Is blding : push ings' , alt_wb) ; 
							// push ings 
							ings.push(alt_wb);
						}
						else {		// found aval wb : do bld
							debug.log( this, ' Found Alt WB  : Do Bld ' , alt_wb) ;  
							avail_wb = alt_wb;
							break;
						}
				}
				
				// re make bTbl 
				this.step3_bld_tbl = ings.concat(this.step3_bld_tbl);
				// do bld  if alter wb is exist 
				if ( avail_wb ) {
	  				this.conductBld ( undefined ,  {type: avail_wb[0] , lv: avail_wb[1] -1 } , // reqres start index with 0 : need -1   
	  						function(task, result) { cb(result); } );	
	  				
	  				return;	// cb is called.. return 
				}

				// exit while loop when no op 
  				break;
				
			} else {

				debug.log( this, 'tryBld :  do Build ~~~~~~~~~~~~~~~~~ : ', wb, cur_wb);
				
				// do bld 
  				this.conductBld ( undefined ,  {type: wb[0] , lv: wb[1] -1 } , // reqres start index with 0 : need -1   
  						function(task, result) { cb(result); } );	
  				
				return;		
			}
			
	  	} // while 
	  	
	  	cb(-1);
	},
	
	// check empty bld slot 
	// get bld table.  
	// check cur bld state 
	// pop done bld action
	// try next bld 
	tryStudy:  function(aparam, cb) {
	  	var cstlinfo = em.cstlmgr.getCurCstl();
	  	
		// check empty study  slot
		cstlinfo.clearExpired (CDB.CDS.STUDY );
		var ings = cstlinfo.findCdTypes (CDB.CDS.STUDY );
		if ( ings.length >= 1 ) {
			debug.log( this, ' All study slot is doing...');
			cb(-1);
			return;
		}

		// get studies 
	  	var cur_state = cstlinfo.studies;
	  	// check cur sty state 
	  	var o_tbl = this.step3_study_tbl;
	  	while ( o_tbl.length !=0  ) {

	  		// get first 
	  		var act = o_tbl.shift() ;
	  		debug.log( this, 'tryStudy :: act: ', act);

	  		// find  entity type  in  cur tbl  [ type, lv, possible]
	  		// got :  [[1,1,1],[2,1,1],[3,0,1]],"ext":[4,4]}; 
	  		var entity = CUtil.findElArrByValPos ( cur_state,  act [0]  /* entity type */ , 0 /* positoin */ );	
	  		debug.log( this, 'tryStudy :: entity: ', entity);
			 
			// if no entity :  <- unable to study due to uni lv 
			if ( !entity ) {
				debug.log( this, 'Unable Study due to Uni Lv ', act);
				o_tbl.unshift( act ) ; // back 
				// eixt loop : will call cb(-1);
				break;
			}
			 
	  		// check already done or need 
	  		if (  entity && entity[1] /* cur lv */  >= act[1] /* want lv */)	{ // lv [1] 
	  			// already done : skip  & remove this.  
	  			continue;
	  		} else {
	  			// need to entity : do  :  when  not exist this study or less   
	  			this.conductStudy ( undefined ,  {tech: act[0] , lv: act[1] -1 } , //   cur lv : want lv - 1 
	  						function(task, result) {
	  							// fail : retry :::   
	  							if ( ! result.succ ) {
	  								o_tbl.unshift( act ) ; // back 
	  								debug.log( self, ' Study Fail::: retry !!')
	  							} 
	  							cb(result); } );	
	  			
	  			// already cb called 
	  			return;
	  		} 
	  	} // while
	  	
	  	cb(-1);
	},
	
	
	// check cur res.g 
	// if g < 200000 :  buy ally tk  & reg trade 
/*
	*******************
* Check G :
*  
*   - find tradelit,  will, trade list : 
*      ==  exist : w no check G
* 
*  - if can find mytem in tradelist 
*  		:skip buy 
* 
*   - if find my tem in  will /trade list
*   	: skip trade  
* 
*/	
	checkG:  function(aparam, cb) {
		var self = this;
		if ( this.step != 3 ) {
			debug.log(this, ' INvalid step .. .not here CheckG');
			cb(-1);
			return;
		}
		
		var cstlinfo = em.cstlmgr.getCurCstl();
				
			function checkG_tryTrade( check_data ) {
				// *   - if find my tem in  will /trade list
				// *   	: skip trade
  				if ( ! check_data.willlist.found &&  ! check_data.mytradelist.found )
  				{
		  			// adjust price
		  			if ( cstlinfo.res.g < self.tem_step3_price / 10 ) {
		  				self.tem_step3_price =  Math.floor ( (cstlinfo.res.g - 10000) *10 / 10000) * 10000  + 89; // xx0089
		  				debug.log( self, ' Less Money::: Adjust new price!! : ' , self.tem_step3_price);
		  			}
		  			// do trade 
	  				 em.tasks.tradeReg (  self.tem_id, 0,  1, self.tem_step3_price, 
	  				// em.tasks.tradeReg (  self.tem_id, 0,  1, 900089, 
		  					function(data) {
			  						if( data.code != 0 ) { debug.log( self, 'ERROR in Trade Reg Ally TK in step 3 ') ;}
			  						else {
				  						self.step3.tradingAllyTk = true;
			  							debug.log( self, ' SUccess Trade Up!!! ', self.tem_id , self.tem_step3_price );
			  							debug.log( self, ' Cur Time :  ', CUtil.TimeToString(new Date() ) );
			  							em.util.print_result( ' SUccess Trade Up!!! ' + self.tem_id + ' p:' +self.tem_step3_price );
			  							em.util.print_result( ' Cur Time :  ' + CUtil.TimeToString(new Date() ) );
			  							em.util.print_result( ' UP Time :  ' + CUtil.TimeToString(new Date($.now() + 15*60*1000) ) );
			  						}
			  						cb(data);
		  					} ); 
  				} 
  				
				if (  check_data.willlist.found || check_data.mytradelist.found){
  					// already trading.. 
  					self.step3.tradingAllyTk = true;
  				}
  				
			}
		

	  	
	  	var g = cstlinfo.res.g;
	  	
	  	// if ( g < 400000  && ! self.step3.tradingAllyTk ) {
	  	 if ( g < 400000  && ! self.step3.tradingAllyTk ) {
		

			
			// Get info from trade list 
			// data.ctx_xxx <- list 
			em.tasks.checkTrade ( self.tem_id , // when buy : id is sid 
		  			function (check_data) {
	  					debug.log( self, ' Result checkTrade  in Step3: ', check_data);
		  				if( check_data.code != 0 ) { 
		  					debug.log( self, 'ERROR in checkTrade  Ally TK in step 3 ') ;
		  					cb(-1);
		  					/// stop 
		  					return;
		  				}
		  				
						
						// *  - if can find mytem in trade tem list 
						// *  		:skip buy 
		  				if ( ! check_data.mylist.found ) {
		  					// try buy
							  		em.tasks.buyItem ( self.tem_type , self.tem_id , // when buy : id is sid 
							  			function (data) {
							  					debug.log( self, ' Result Buy Tem in Step3: ', data);
								  				if( data.code != 0 ) { 
								  					debug.log( self, 'ERROR in buy  Ally TK in step 3 : no Money??? ') ;
								  					cb(-1);
								  					/// stop 
								  					return;
								  				}
								  				
							  				// try trade 
											checkG_tryTrade (check_data);
							  			}); 
		  				} else {
			  				// try trade 
							checkG_tryTrade (check_data);
		  				}
		  				
		  			} // check trade cb 
		  	);
		
	  } // if g < 
	  
	  	// done nothing 
		cb(-1);
	},
	
	
	tryDonate:  function(aparam, cb) {
		cb(1);
	/*
		  var cstlinfo = em.cstlmgr.getCurCstl();
						   // check empty study  slot
			var bld_cds = cstlinfo.findCdTypes (CDB.CDS.STUDY );
			if ( bld_cds.length >= 1 ) {
				debug.log( this, ' All study slot is doing...');
				cb(-1);
				return;
			}
	
			// get studies 
			  var cur_state = cstlinfo.studies;
			  // check cur sty state 
			  var o_tbl = this.step3_study_tbl;
			  while ( o_tbl.length !=0  ) {
					   // get first 
				  var act = o_tbl.shift() ;
					   // find  entity type  in  cur tbl  [ type, possible, lv]
				  // got :  [[1,1,1],[2,1,1],[3,0,1]],"ext":[4,4]}; 
									 // check already done or need 
				  // if ( entity[2]>= act[1] )	{ // lv [1] 
					  // already done : skip  & remove this.  
					  continue;
				  } else {
					  // need to entity : do  
					  this.conductStudy ( undefined ,  {tech: act[0] , lv: act[1] -1 } , //   cur lv : want lv - 1 
								  function(task, result) { cb(result); } );	
					  break;
				  } 
			  } // for */
	
	},
	
	// ================================================ 
	// each  task    
	
	
	___EACH_FUNCTION_DEFINE______: function() {} ,
	// 1 shot task :  use ahelper  : direct cb 
	getGift: function( task,  code, cb ) {
		
		var self = this;
		debug.log(this, 'this', this, task);
		// use action helper
	 	var username = CDB.getCurUser();
		var param = { 'user': username, 'code': code,  
				cb : function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					} 
				};
		em.ahelper.gift(param);		
	},
		/*
			GET /game/get_userinfo_api.php?jsonpcallback=jsonp1326014287292&_=1326016300674&key=0314fac3e037989c062370584d3dc99b&_l=en&_p=EW-DROID HTTP/1.1

		*/
	getUserInfo:  function( task,  param ,cb ) {
		
		var self = this;
		debug.log(this, 'this', this, task);
		// use action helper
		var param = { 
				cb : function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					} 
				};
		em.ahelper.get_userinfo_api(param);		
	},
	trainSol:  function( task,  param , cb) {
		
		var self = this;
		debug.log(this, 'this', this, task);

		em.tasks.trainSol(em.cstlmgr.getCurCstlIdx(), 
					{type : param.sol_type , num : param.sol_num },
					{} ,  // exchange res 
					function (data) {
						// succ/ fail check
						if ( data.code == 0 ) {
							data.succ = true;
							// move cstl to update new res 
							var cb_cstlmove ;
							em.cbs.cstlmove1done.add( cb_cstlmove = function () { 
							em.cbs.cstlmove1done.remove( cb_cstlmove);
							if( cb) {	cb.apply (self, [ task, data ]);	}	 
							}  ); 
							
							em.cstlmgr.moveCstlAt( em.cstlmgr.getCurCstlIdx() );
						} else {
							data.succ = false;	
							debug.log( self, ' TRain Fail... ', data);
							if( cb) {	cb.apply (self, [ task, data ]);	}	  
						}
					} 
					);
	},
	
	buyGemItem:  function( task,  param , cb) {
		var self = this;
		debug.log(this, 'this', this, task);

		em.tasks.buyGemItem(	 param.cat , param.id ,
					function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	 	 
					} 
					);
	},
	
	hireH:  function( task,  param , cb) {
		
		var self = this;
		debug.log(this, 'this', this, task);

		em.tasks.hireH( 
					function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	 	 
					} 
					);
	},
	
							
	// use dfd . tasks : when  		
	// if task == undefined.  do not go next 
	conductBld	: function( task,  param , cb ) {
		var self = this;
		var dfd = $.Deferred();

		// only success
		$.when(dfd).then( function(result) {
			//	{"code":0,"ret":{
// 			// "cdlist":[{"id":847443,"cdtype":1,"target":"8","owner":0,"secs":521}]}})
						debug.log(self, 'ret BUILD Success!!', result);
						if ( result.code == 0 ) result.succ = true;
						
						// move cstl to update new res 
						var cb_cstlmove ;
						em.cbs.cstlmove1done.add( cb_cstlmove = function () { 
						em.cbs.cstlmove1done.remove( cb_cstlmove);
						if( cb) {	cb.apply (self, [ task, result ]);	}	 
						}  ); 
						
						em.cstlmgr.moveCstlAt( em.cstlmgr.getCurCstlIdx() );
						
						// if( cb) {	cb.apply (self, [ task, result ]);	}	 
					}
					, function(result) {
						var error_str = '';
						if( result.code == 704 ) error_str = 'no slot for bld: need bless of bld'; 
						if( result.code == 708 ) error_str = 'Need more Res.. check !!'; 
						//alert('build fail :' + result.code + error_str);
						result.succ = false;
						if( cb) {	cb.apply (self, [ task, result ]);	}	 
					}
		);

		var type = param.type;
		var lv = param.lv ;
		debug.log( this, ' param: type ', type, 'lv:', lv);
		
		// calc res  : compare to cstl res 
		var res  = em.cstlmgr.getCurCstl().res;
		// remain minimum f : 
		var cost = CDB.getBuildRes(type, lv) ;	
		//cost.f += CDB.getCurUserInfo().MinFood;
		debug.log( this, ' build Need cost: ', cost);


		var calc_ret = {} ;
		if ( ! cost ) {	// no info build cost : not important.. just build 
			calc_ret =  {'possible': true, 'exchange': {f:0, w:0, i:0 , total: 0 } };			
		}  else {
			calc_ret = CUtil.calcNeedRes(res, cost);
		}

		em.tasks.doBuild( dfd, type, {g2f: calc_ret.exchange.f,  g2w: calc_ret.exchange.w, g2i: calc_ret.exchange.i, total:calc_ret.exchange.total }  );
		
	},		
		
	// use dfd . tasks : when  		
	conductStudy	: function( task,  param , cb ) {
		var self = this;
	
		debug.log(this, 'conductStudy ', param);
		
		// calc res  : compare to cstl res 
		var res  = em.cstlmgr.getCurCstl().res;
		var cost = CDB.getStudyRes( param.tech, param.lv) ;	
		debug.log( this, ' getStudyRes Need cost: ',  cost , 'cur res: ', res);
		var calc_ret = CUtil.calcNeedRes(res, cost);

		// check possible 
		if ( ! calc_ret.possible  ) {
		//	alert(' Not Enough Res!!');
			// update status ... 
										debug.log(this, 'Not Enough Res!!  IN conductStudy  ' );
			if( cb) {	cb.apply (self, [ task, {succ:false} ]);	}
			return;
		}
		
		var dfd = $.Deferred();

		// OK : COLOR -> YELLOW
		// result - > cd list  update to cstlmgr by tasks 
		function processRet(result) {
				debug.log( self, 'conductStudy : result ', result);
				if (result.code == 0 && result.ret && result.ret.cdlist ) {
					result.succ = true;
					debug.log(self, 'ret Sutdy Success!!', result);
				
					// move cstl to update new res
					var cb_cstlmove ;
					em.cbs.cstlmove1done.add( cb_cstlmove = function () { 
						em.cbs.cstlmove1done.remove( cb_cstlmove);
						if( cb) {	cb.apply (self, [ task, result ]);	}	 
						}  ); 

					em.cstlmgr.moveCstlAt( em.cstlmgr.getCurCstlIdx() );

				} else {
					debug.log( self, 'conductStudy : FAIL ', result );
					if( cb) {	cb.apply (self, [ task, result ]);	}	 
				}


		};	
		
		// only success
		$.when(dfd).then( processRet, processRet );


		em.tasks.doStudy( dfd, param.tech, 
				{g2f: calc_ret.exchange.f,  g2w: calc_ret.exchange.w, g2i: calc_ret.exchange.i, total:calc_ret.exchange.total }  );
							
	},			
				
	// 1 shot task :   use ahelper  : direct cb 
	conductQst: function( task,  param , cb) {
		
		var self = this;
		
		function conductTask() {
			// use action helper
			var conduct_param = {   'action': param.action, 'id': param.id, 
					cb : function (data) {
						//  task_up :  "code":0,"ret":{"status":2}})
						//  task_end : {"code":0,"ret":{"quest":[{"id":48,"grade":0,"status":0,"done":0}]}})
								// {"id":46,"grade":0,"status":1,"done":0},		//  status : accepted ,  not done
	// 							 		{"id":48,"grade":0,"status":0,"done":1},		// status : 0,  done : done ...
							// succ/ fail check 
							if ( data.code == 0 ) data.succ = true;
							if( cb) {	cb.apply (self, [ task, data ]);	}	 
						} 
					};
			em.ahelper.system_task_conduct (conduct_param);
			return;		
		};
		
		// first  get task list 
		var tasklist_param = { action: 'task_list', cb : function (data) {
									debug.log( self, 'SystemTask List : ', data);
									conductTask();
									}	};
		em.ahelper.system_task_api (tasklist_param);
	},
	
	useItem: function( task,  param, cb ) {
		
		var self = this;
		
// 		GET /game/
/*

// use ref gift 

goods_api.php?jsonpcallback=jsonp1326014287249&_=1326014559916&key=0314fac3e037989c062370584d3dc99b
&action=goods_list
&type=3
&page=1
&_l=en&_p=EW-DROID HTTP/1.1


jsonp1326014287249({"code":0,"ret":{"max":1,
"item":[{"item":
{"id":75614,"sid":167,"num":1},"use":1,"sale":0},
{"item":{"id":75612,"sid":128,"num":1},"use":1,"sale":0},
{"item":{"id":75616,"sid":190,"num":1},"use":1,"sale":50000},
{"item":{"id":75609,"sid":168,"num":1},"use":1,"sale":0},
{"item":{"id":75615,"sid":188,"num":1},"use":2,"sale":0},
{"item":{"id":75611,"sid":126,"num":1},"use":1,"sale":0},
{"item":{"id":75606,"sid":169,"num":1},"use":1,"sale":0},
{"item":{"id":75613,"sid":161,"num":2},"use":1,"sale":0},
{"item":{"id":75610,"sid":80,"num":1},"use":1,"sale":0}]}})




GET /game/
goods_mod_api.php?jsonpcallback=jsonp1326014287250&_=1326014568812&key=0314fac3e037989c062370584d3dc99b
&action=use
&city=17736
&id=75614
&num=1
&_l=en&_p=EW-DROID HTTP/1.1

jsonp1326014287250({"code":0,"ret":
{"item":[],"gem":0,"buff":
{"id":6381,"itemid":167,"secs":2592000},"wood":0,"food":0,"iron":0,"gold":0}})

list one more : updtae cur page 


GET /game/goods_mod_api.php?jsonpcallback=jsonp1326014287252&_=1326014587093&key=0314fac3e037989c062370584d3dc99b
&action=use
&city=17736
&id=75606
&num=1
&_l=en&_p=EW-DROID HTTP/1.1

jsonp1326014287252({"code":0,"ret":
{"item":[
{"id":0,"sid":153,"num":1},
{"id":0,"sid":115,"num":3},
{"id":0,"sid":118,"num":3},
{"id":0,"sid":161,"num":3}],"gem":0,
"buff":"","wood":0,"food":0,"iron":0,"gold":0}})


list one more : updtae cur page 




////////////// use chest 


/// use item  : item list 
GET /game/
goods_api.php?jsonpcallback=jsonp1326014287328&_=1326017016998&key=0314fac3e037989c062370584d3dc99b
&action=goods_list
&type=3
&page=1
&_l=en&_p=EW-DROID HTTP/1.1

jsonp1326014287328({"code":0,"ret":{"max":2,"item":[{"item":{"id":75612,"sid":128,"num":1},"use":1,"sale":0},{"item":{"id":75616,"sid":190,"num":1},"use":1,"sale":50000},{"item":{"id":75609,"sid":168,"num":1},"use":1,"sale":0},{"item":{"id":75618,"sid":115,"num":3},"use":2,"sale":0},{"item":{"id":75615,"sid":188,"num":1},"use":2,"sale":0},{"item":{"id":75619,"sid":118,"num":3},"use":2,"sale":0},{"item":{"id":75611,"sid":126,"num":1},"use":1,"sale":0},{"item":{"id":75613,"sid":161,"num":2},"use":1,"sale":0},{"item":{"id":75620,"sid":161,"num":3},"use":1,"sale":0},{"item":{"id":75644,"sid":131,"num":1},"use":1,"sale":0}]}})

// use chest 
GET /game/
goods_mod_api.php?jsonpcallback=jsonp1326014287329&_=1326017033995&key=0314fac3e037989c062370584d3dc99b
&action=use
&city=17736
&id=75644
&num=1
&_l=en&_p=EW-DROID HTTP/1.1


jsonp1326014287329({"code":0,"ret":
{"item":[],"gem":0,"buff":"","wood":0,"food":0,"iron":0,
"gold":30000}})


// update 
jsonp1326014287328({"code":0,"ret":{"max":2,"item":[
{"item":{"id":75612,"sid":128,"num":1},"use":1,"sale":0},
{"item":{"id":75616,"sid":190,"num":1},"use":1,"sale":50000},
{"item":{"id":75609,"sid":168,"num":1},"use":1,"sale":0},
{"item":{"id":75618,"sid":115,"num":3},"use":2,"sale":0},
{"item":{"id":75615,"sid":188,"num":1},"use":2,"sale":0},
{"item":{"id":75619,"sid":118,"num":3},"use":2,"sale":0},
{"item":{"id":75611,"sid":126,"num":1},"use":1,"sale":0},
{"item":{"id":75613,"sid":161,"num":2},"use":1,"sale":0},
{"item":{"id":75620,"sid":161,"num":3},"use":1,"sale":0},
{"item":{"id":75644,"sid":131,"num":1},"use":1,"sale":0}]}})



*/

		em.tasks.useItem ( param.type, param.sid, param.id,  param.num, 
					function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					}
					);	
		
	},
/*
	sell
*/


	saleItem: function( task,  param , cb) {
		
		var self = this;
		
		em.tasks.saleItem( param.type, param.sid, param.id, param.num , 
					function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					}
					);	
		
	},
// buy shop normal item 
buyItem: function( task,  param , cb ) {
		
		var self = this;
		
		em.tasks.buyItem ( param.type, param.id, 
					function (data) {
						// succ/ fail check 
						data.succ = true;
						
						// jsonp1326014287360({"code":0,"ret":{"gold":32708,"itemid":75656}})
						// save all token id  : for registering. 
						self.allyTokenId =  data.ret.itemid; 
						
						debug.log( this, '\t\t BUY TEM  : ID  : ', self.allyTokenId);
						
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					}
					);	
		
	},

	tradeReg: function( task,  param ,cb ) {
		
		var self = this;
		
		param.id = self.allyTokenId;
		debug.log( this, ' \t\t Trade Reg : ', param);
		debug.log( this, ' \t\t Trade Reg :: TEM.ID : ', param.id);
		
		em.tasks.tradeReg (  param.sid, param.id,  param.num, param.price, 
					function (data) {
						// succ/ fail check
						
						// when succ 
						// {"code":0,"ret":{"item":[[2756,113,310089,832]],"max":1}}) 
						if ( data.code == 0 && data.step == 'will') {
							data.succ = true;
							self.tradeRemains = data.ret.item[3];
						} else {
							data.succ = false;
  							debug.log( self, ' SUccess Trade Up!!! ', param.sid, param.id,  param.num, param.price );
  							debug.log( self, ' Cur Time :  ', CUtil.TimeToString(new Date() ) );							
						}
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					}
					);	
		
	},

	checkTrade: function( task,  param ,cb ) {
		var self = this;
		debug.log( this, ' \t\t checkTrade Reg :: TEM.ID : ', param.sid);
		
			em.tasks.checkTrade ( param.sid , // when check with sid  
		  			function (check_data) {
	  					debug.log( self, ' Result checkTrade  in Step3: ', check_data);
		  				if( check_data.code != 0 ) { 
		  					debug.log( self, 'ERROR in checkTrade  Ally TK in step  ', self.step ) ;
		  					check_data.succ = false;
		  				} else {
			  				if (  check_data.willlist.found || check_data.mytradelist.found){
			  					debug.log( self, 'ERROR in checkTrade  Ally TK in step  ', self.step ) ;
			  					em.util.print_result( '\n\n Trade tem is On the List  \n\n\n <br/>' + CUtil.SecToString( check_data.willlist.remainsec) );	 
			  					em.util.print_result( '<br/> UP Time :  ' + CUtil.TimeToString( new Date( $.now() + check_data.willlist.remainsec * 1000) ) ); 
			  				}
			  				check_data.succ = true;
		  				}
						if( cb) {	cb.apply (self, [ task, check_data ]);	}		  				
		  			}
		  			);
	},
/*
	GET /game/
	goods_mod_api.php?jsonpcallback=jsonp1326014287254&_=1326014610596&key=0314fac3e037989c062370584d3dc99b
	&action=sale
	&city=17736
	&id=75616
	&_l=en&_p=EW-DROID HTTP/1.1

*/
	// 1 shot task :   use ahelper  : direct cb 
	checkCd: function( task,  param , cb ) {
		var self = this;
		
		// timer 
		function  checkCdTimeFn() {
			// get cd type
			// finish check ?   
			// ok - remove cd . 
			// go next : 
				debug.log(self, ' checkCdTimeFn for task completion :');
					// check cdlist
					
					var bCompleted =  em.cstlmgr.bCompleteCdlist(param.cdtype, param.target );
					
					debug.log(this, 'complete ? :', bCompleted);
					if (  bCompleted  ) {
						// clear this timer 
						clearTimeout( self.cd_timer);
						
						// get cd info when complete cd 
						em.tasks.getCDInfo(em.cstlmgr.curCstlID(),
							 function ( data ) {
								// send task to do next
								var data  = { succ: true};
								if( cb) {	cb.apply (self, [ task, data ]);	}	 
						});
						
					} else {
						// set next timeout 
						self.cd_timer = setTimeout( checkCdTimeFn , 10000);
					} 
			
					 
		};
		// set timer :  first 
		this.cd_timer = setTimeout( checkCdTimeFn , 0);
		
		// check cd list of cur cstl   
		
		
		 
		
		
	},	
};

		